package com.tudouji.project.customer.service.impl;

import com.flow.service.pojo.BasePojo;
import com.flow.service.pojo.ResultParam;
import com.flow.service.pojo.result.FlowResult;
import com.flow.service.process.service.IFlowBaseService;
import com.github.pagehelper.PageHelper;
import com.tudouji.common.utils.DateUtils;
import com.tudouji.common.utils.IdUtils;
import com.tudouji.common.utils.SecurityUtils;
import com.tudouji.common.utils.sql.SqlUtil;
import com.tudouji.framework.web.domain.AjaxResult;
import com.tudouji.framework.web.page.PageDomain;
import com.tudouji.framework.web.page.TableSupport;
import com.tudouji.project.bill.domain.Recharge;
import com.tudouji.project.bill.domain.Sellform;
import com.tudouji.project.bill.service.impl.SellformServiceImpl;
import com.tudouji.project.customer.domain.*;
import com.tudouji.project.customer.mapper.*;
import com.tudouji.project.customer.service.ICustomerService;
import com.tudouji.project.flow.utils.FlowProcessUtil;
import com.tudouji.project.permission.domain.Salespermission;
import com.tudouji.project.permission.service.impl.SalespermissionServiceImpl;
import com.tudouji.project.system.domain.SysUser;
import com.tudouji.project.system.service.impl.BusinesscodeServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import static com.tudouji.common.utils.DateUtils.*;

/**
 * 客户管理Service业务层处理
 *
 * @author wf
 * @date 2020-12-30
 */
@Slf4j
@Service
public class CustomerServiceImpl implements ICustomerService, IFlowBaseService {
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private CustomerdepartgroupMapper customerdepartgroupMapper;
    @Autowired
    private SalespermissionServiceImpl permissionService;
    @Autowired
    private CustbaseinfoMapper custbaseinfoMapper;
    @Autowired
    private FinanceinfoMapper financeinfoMapper;
    @Autowired
    private CashflowMapper cashflowMapper;
    @Autowired
    private ReceivableflowMapper receivableflowMapper;
    @Autowired
    private FlowProcessUtil processUtils;
    @Autowired
    private BusinesscodeServiceImpl businesscodeService;
    @Autowired
    private SellformServiceImpl sellformService;

    /**
     * 查询客户管理
     *
     * @param guid 客户管理ID
     * @return 客户管理
     */
    @Override
    public Customer selectCustomerById(String guid) {
        return customerMapper.selectCustomerById(guid);
    }


    /**
     * 查询客户管理列表
     *
     * @param customer 客户管理
     * @return 客户管理
     */
    @Override
    public List<Customer> selectCustomerList(Customer customer) {
        return customerMapper.selectCustomerList(customer);
    }
    @Override
    public BigDecimal selectCustomerListSum(Customer customer) {
        return customerMapper.selectCustomerListSum(customer);
    }

    /**
     * 新增客户管理
     *
     * @param customer 客户管理
     * @return 结果
     */
    @Override
    public int insertCustomer(Customer customer) {
        customer.setGuid(IdUtils.fastSimpleUUID());
        customer.setOperator(SecurityUtils.getLoginUser().getUser().getNickName());
        customer.setOperatorid(SecurityUtils.getLoginUser().getUser().getUserId().toString());
        customer.setCreatetime(getNowDate());
        return customerMapper.insertCustomer(customer);
    }

    /**
     * 修改客户管理
     *
     * @param customer 客户管理
     * @return 结果
     */
    @Override
    public int updateCustomer(Customer customer) {
        return customerMapper.updateCustomer(customer);
    }
    @Override
    public int updateCustomerWx(Customer customer) {
        return customerMapper.updateCustomer(customer);
    }

    /**
     * 批量删除客户管理
     *
     * @param guids 需要删除的客户管理ID
     * @return 结果
     */
    @Override
    public int deleteCustomerByIds(String[] guids) {
        return customerMapper.deleteCustomerByIds(guids);
    }

    /**
     * 删除客户管理信息
     *
     * @param guid 客户管理ID
     * @return 结果
     */
    @Override
    public int deleteCustomerById(String guid) {
        return customerMapper.deleteCustomerById(guid);
    }


    /**
     * @param @return void @throws
     * @Title: SxettingProv
     * @Description: 设置区域信息
     */
    public void settingProv(Customer customer) {
//        获取传入的省信息
        String province = customer.getProvince();
        if (StringUtils.isEmpty(province)) {
            log.error("未传入所属区域，程序不进行处理！");
        } else {
            String[] provinces = province.split(" ");
            if (provinces.length == 1) {
                customer.setProvince(provinces[0]);
            } else if (provinces.length == 2) {
                customer.setProvince(provinces[0]);
                customer.setCity(provinces[0]);
//                区
                customer.setDistrict(provinces[1]);
            } else {
                customer.setProvince(provinces[0]);
                customer.setCity(provinces[1]);
                customer.setDistrict(provinces[2]);
            }
        }
    }

//                仅支持当前事务，如果当前没有事务就新建一个事务                   异常回滚
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult save(Customer customer, String fileIds) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (null == customer.getId()) {
            //判断是否有重名
            Customer cust = customerMapper.selectCustomerByName(customer.getName());
            if (cust == null) {
//                新增客户
                customer.setOperatorid(user.getGuid());
                customer.setOperator(user.getNickName());
                settingProv(customer);
                customer.setStatus(0);
                String guid = IdUtils.fastSimpleUUID();
                customer.setGuid(guid);
                customer.setCreateBy(user.getUserId());
                customer.setCreateName(user.getNickName());
                customer.setFlowid(29L);
                customer.setCreatetime(getNowDate());
//              32为客户编码
                customer.setCode(businesscodeService.getCode("32"));
                customerMapper.insertCustomer(customer);

//                新增客户经营情况
                Custbaseinfo base = customer.getBaseinfo();
                if (base == null) {
                    base = new Custbaseinfo();
                }
                base.setCustomerid(guid);
                base.setOperator(customer.getOperator());
                base.setOperatorid(customer.getOperatorid());
                base.setGuid(IdUtils.fastSimpleUUID());
                base.setCreatetime(getNowDate());
                custbaseinfoMapper.insertCustbaseinfo(base);

//                新增客户财务情况
                Financeinfo finance = customer.getFinanceinfo();
                if (finance == null) {
                    finance = new Financeinfo();
                }
                finance.setCustomerid(guid);
                finance.setOperator(customer.getOperator());
                finance.setOperatorid(customer.getOperatorid());
                finance.setGuid(IdUtils.fastSimpleUUID());
                finance.setCreatetime(getNowDate());
                financeinfoMapper.insertFinanceinfo(finance);
            } else {
                return AjaxResult.error("客户已存在！");
            }
        } else {
//            修改客户信息
            customerMapper.updatenCustomerNew(customer);
//            修改客户经营情况
            Custbaseinfo base = customer.getBaseinfo();
            if (base != null && org.apache.commons.lang.StringUtils.isNotBlank(base.getGuid())) {
                custbaseinfoMapper.updateCustbaseinfo(base);
            }
//            修改客户财务情况
            Financeinfo finance = customer.getFinanceinfo();
            if (finance != null && org.apache.commons.lang.StringUtils.isNotBlank(finance.getGuid())) {
                financeinfoMapper.updateFinanceinfo(finance);
            }
//            更新流程状态为已处理
            Customer cust = customerMapper.selectCustomerByNewId(customer.getId());
            processUtils.updateTaskByOrderId(cust.getId(), user, cust.getFlowid());
        }

////        设置客户经理关系
//        customer = customerMapper.selectCustomerByNewId(customer.getId());
//        String guid = customer.getGuid();
//        Customerdepartgroup customerdepartgroup = new Customerdepartgroup();
//        customerdepartgroup.setCustomerid(guid);
//        customerdepartgroup.setSellerid(user.getTuserId());
//        customerdepartgroup.setStatus(0);
//        customerdepartgroup.setType(2);
//        customerdepartgroup.setOperatorid(user.getTuserId());
//        customerdepartgroup.setOperator(user.getNickName());
//        customerdepartgroup.setCreatetime(new Date());
//        customerdepartgroup.setGuid(IdUtils.fastSimpleUUID());
//        this.customerdepartgroupMapper.insertCustomerdepartgroup(customerdepartgroup);

        // 获取起始节点

        Long startNodeId = processUtils.getStartNode(customer.getFlowid());
        FlowResult result = processUtils.defaultStart(startNodeId, customer, fileIds, user);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Customer pb = new Customer();
            pb.setGuid(customer.getGuid());
            pb.setStatus(result.getNextStat());
            this.updateCustomer(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult confirm(Long id, String imgids, String opinion, Long taskid) {
//        根据id查询得到客户
        Customer customer = customerMapper.selectCustomerByNewId(id);
        SysUser user = SecurityUtils.getLoginUser().getUser();

//        设置客户经理
        String guid=customer.getGuid();
        Customerdepartgroup customerdepartgroup=new Customerdepartgroup();
        customerdepartgroup.setCustomerid(guid);
        customerdepartgroup.setSellerid(customer.getOperatorid());
        customerdepartgroup.setStatus(1);
        customerdepartgroup.setType(2);
        customerdepartgroup.setOperatorid(user.getTuserId());
        customerdepartgroup.setOperator(user.getNickName());
        customerdepartgroup.setCreatetime(new Date());
        customerdepartgroup.setGuid(IdUtils.fastSimpleUUID());
        this.customerdepartgroupMapper.insertCustomerdepartgroup(customerdepartgroup);

////        取到客户对象主键
//        String guid = customer.getGuid();
////        得到部门与客户的关联对象
//        Customerdepartgroup customerdepartgroup = new Customerdepartgroup();
////        把客户对象主键设置为关联对象客户id
//        customerdepartgroup.setCustomerid(guid);
////        把客户对象创建人id设置为部门与客户的关联对象的销售员id
//        customerdepartgroup.setSellerid(customer.getOperatorid());
////        把部门与客户的关联对象的状态设置为正常
//        customerdepartgroup.setStatus(1);
////        通过销售员修改修改部门与人员关系对象
//        this.customerdepartgroupMapper.updateCustomerdepartgroupBySeller(customerdepartgroup);

        FlowResult result = processUtils.defaultApproval(taskid, imgids, opinion, customer
                , user);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Customer pb = new Customer();
            pb.setStatus(result.getNextStat());
            pb.setGuid(customer.getGuid());
            this.updateCustomer(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult approval(Long id, String imgids, String opinion, Long taskid) {
//        根据id查询得到客户
        Customer customer = customerMapper.selectCustomerByNewId(id);
        SysUser user = SecurityUtils.getLoginUser().getUser();

//        取到客户对象主键
        String guid = customer.getGuid();
//        得到部门与客户的关联对象
        Customerdepartgroup customerdepartgroup = new Customerdepartgroup();
//        把客户对象主键设置为关联对象客户id
        customerdepartgroup.setCustomerid(guid);
//        把客户对象创建人id设置为部门与客户的关联对象的销售员id
        customerdepartgroup.setSellerid(customer.getOperatorid());
//        把部门与客户的关联对象的状态设置为正常
        customerdepartgroup.setStatus(1);
//        通过销售员修改修改部门与人员关系对象
        this.customerdepartgroupMapper.updateCustomerdepartgroupBySeller(customerdepartgroup);

        FlowResult result = processUtils.defaultApproval(taskid, imgids, opinion, customer
                , user);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Customer pb = new Customer();
            pb.setStatus(result.getNextStat());
            pb.setGuid(customer.getGuid());
            this.updateCustomer(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    public AjaxResult refuse(Long id, String fileIds, String opinion, Long taskid, Long refuseNodeid, Long backUserid) {
//        根据id得到客户
        Customer customer = customerMapper.selectCustomerByNewId(id);
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();

        FlowResult result = processUtils.defaultRefuse(taskid, fileIds, opinion, customer
                , sysUser, refuseNodeid, backUserid);

        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            Customer pb = new Customer();
//            把客户对象设置为result的
            pb.setStatus(result.getNextStat());
            pb.setGuid(customer.getGuid());
            this.updateCustomer(pb);
            return AjaxResult.success();
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(result.getMsg());
        }
    }

    @Override
    public AjaxResult unable(Long id) {
        Customer customer = customerMapper.selectCustomerByNewId(id);

        Customer pb = new Customer();
        if (1 == customer.getStatus()) {
            pb.setStatus(2);
        }
        if (2 == customer.getStatus()) {
            pb.setStatus(1);
        }
        pb.setGuid(customer.getGuid());
        this.updateCustomer(pb);
        return AjaxResult.success();
    }


    /**
     * 设置请求分页数据
     */
    protected void startPage() {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (com.tudouji.common.utils.StringUtils.isNotNull(pageNum) && com.tudouji.common.utils.StringUtils.isNotNull(pageSize)) {
            String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }
    }

    @Override
    public List<Customer> selectCustomerWxList(Customer customer, String status, String functionType) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if (customer == null) {
            customer = new Customer();
        }

        if (org.apache.commons.lang.StringUtils.isNotBlank(status)) {
            // 待处理
            if (status.equals("00")) {
                startPage();
                customer.setCreateBy(sysUser.getUserId());
                return customerMapper.selectCustomerPendingList(customer);
            }
        }
        //查询是否有全局权限
        List<Salespermission> permissions = permissionService.getPermByScAndFuncSYS(sysUser.getUserId(), functionType, "4");
        if (permissions.size() > 0) {
            startPage();
            return customerMapper.selectCustomerList(customer);
        } else {
            customer.setCreateBy(sysUser.getUserId());
            customer.setType(1);
            customer.setSellerid(sysUser.getTuserId());
            permissions = permissionService.getPermByScAndFunc(sysUser.getGuid(), functionType, "2");
            startPage();
            if (permissions.size() > 0) {
                String[] departids = new String[permissions.size()];
                for (int i = 0; i < permissions.size(); i++) {
                    departids[i] = permissions.get(i).getDepartid();
                }
                customer.setDeptids(departids);
            }
            return customerMapper.selectCustomerListByUser(customer);
        }
    }

    @Override
    public AjaxResult detail(Long id) {
        // 客户基本信息
        Customer cust = customerMapper.selectCustomerByNewId(id);
        //新销售订单预收款余额判断逻辑，过渡期两种判断的和才能确定
        HashMap<String, Object> newPrebalanceMap = sellformService.getPrebalanceZYNew(cust.getGuid());
        //在途ztbalance
        BigDecimal ordersbalance1New = newPrebalanceMap.get("ordersbalance1") == null ? BigDecimal.ZERO : (BigDecimal)newPrebalanceMap.get("ordersbalance1");
        BigDecimal ordersbalanced1New = newPrebalanceMap.get("ordersbalanced1") == null ? BigDecimal.ZERO : (BigDecimal)newPrebalanceMap.get("ordersbalanced1");
        BigDecimal ztbalance = ordersbalance1New.add(ordersbalanced1New);
        cust.setCurrprebalance(cust.getCurrprebalance().subtract(ztbalance).setScale(2, BigDecimal.ROUND_HALF_UP));
        cust.setPrebalance(cust.getPrebalance().subtract(ztbalance).setScale(2, BigDecimal.ROUND_HALF_UP));
//        客户主键
        String customerid = cust.getGuid();
        // 客户经营信息（根据主键得到）
        Custbaseinfo baseinfo = custbaseinfoMapper.selectCustbaseinfoByCustomerid(customerid);
        cust.setBaseinfo(baseinfo);
        // 客户财务信息
        Financeinfo financeinfo = financeinfoMapper.selectFinanceinfoByCustomerId(customerid);
        cust.setFinanceinfo(financeinfo);
        // 余额流水
        Cashflow flow = new Cashflow();
        flow.setCustomerid(customerid);
        List<Cashflow> cashflows = cashflowMapper.selectCashflowList(flow);
        cust.setCashflows(cashflows);
        // 应收账款流水
        Receivableflow rflow = new Receivableflow();
        rflow.setCustomerid(customerid);
        List<Receivableflow> receivableflows = receivableflowMapper.selectReceivableflowList(rflow);
        cust.setReceivableflows(receivableflows);

        return AjaxResult.success(cust);
    }

    @Override
    public AjaxResult prebalancedetail(Long id) {
        // 客户基本信息
        Customer cust = customerMapper.selectCustomerByNewId(id);
        //得到客户主键
        String customerid = cust.getGuid();

        //新销售订单预收款余额判断逻辑，过渡期两种判断的和才能确定
        HashMap<String, Object> newPrebalanceMap = sellformService.getPrebalanceZYNew(customerid);
        //在途ztbalance
        BigDecimal ordersbalance1New = newPrebalanceMap.get("ordersbalance1") == null ? BigDecimal.ZERO : (BigDecimal)newPrebalanceMap.get("ordersbalance1");
        BigDecimal ordersbalanced1New = newPrebalanceMap.get("ordersbalanced1") == null ? BigDecimal.ZERO : (BigDecimal)newPrebalanceMap.get("ordersbalanced1");
        List<Sellform> sellformNews = (List<Sellform>)newPrebalanceMap.get("sellformNews");
        BigDecimal ztbalance = ordersbalance1New.add(ordersbalanced1New);
        cust.setPrebalanceUsabling(ztbalance);
        cust.setPrebalanceUsable(cust.getPrebalance().subtract(ztbalance).setScale(2, BigDecimal.ROUND_HALF_UP));

        // 交易记录
        Cashflow flow = new Cashflow();
        flow.setCustomerid(customerid);
        List<Cashflow> cashflows = cashflowMapper.selectCashflowList(flow);
        cust.setCashflows(cashflows);

        //在途订单
        cust.setSellforms(sellformNews);

        return AjaxResult.success(cust);
    }

    @Override
    public AjaxResult del(Long id) {
        Customer customer = customerMapper.selectCustomerByNewId(id);
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (customer.getStatus() < 1) {
            Customer cust = new Customer();
            cust.setId(id);
            cust.setStatus(0);
            customerMapper.updatenCustomerNew(cust);
            //更新待处理任务
            processUtils.updateTaskByOrderId(id, user, customer.getFlowid());
            return AjaxResult.success();
        } else {
            return AjaxResult.error("审批完成，不能删除");
        }
    }

    @Override
    public List<Customer> getCustomers(String departId, String functionType) {
        SysUser user = SecurityUtils.getLoginUser().getUser();

        List<Customer> customers = new ArrayList<>();
        // 查询授权全局客户
        /*List<Salespermission> permissionsAll = permissionService.getPermByScAndFunc(user.getTuserId(), functionType, "4");
        if (permissionsAll.size() > 0) {
            Customer customer = new Customer();
            customer.setStatus(1);//100
            customer.setType(1);
            customers = customerMapper.selectCustomers(customer);
            return customers;
        }*/
        // 查询授权部门下的客户
        Customerdepartgroup cust = new Customerdepartgroup();
        cust.setStatus(1);
        String[] departids = {departId};
        cust.setType(1);
        cust.setDepartids(departids);
        cust.setSellerid(user.getGuid());
        customers = customerMapper.getCustomers(cust);
        if (customers.size() > 0) {
            return customers;
        } else {
            // 查询客户经理名下客户
            cust.setDepartids(null);
            cust.setSellerid(user.getGuid());
            cust.setType(2);
            customers = customerMapper.getCustomers(cust);
            return customers;
        }
    }

    /**
     * 客户充值或充值记录的核销
     * @param customer      客户
     * @param amount        发生额
     * @param user          操作用户
     * @param recharge      充值实体，如果是充值流程调用的话则传入
     * @param type          类型 1 - 充值  2 - 条码（已弃用）  3-核销时利用销售订单冲销预收款
     */
    @Override
    public void recharge(Customer customer, BigDecimal amount, SysUser user, Recharge recharge,int type,String remark) {
        // 写入充值记录 ,更新预付款余额
        Cashflow cashflow = new Cashflow();
        cashflow.setCustomerid(customer.getGuid());
        if(recharge!=null){
            cashflow.setCode(recharge.getCode());
            cashflow.setLinkid(recharge.getGuid());
            cashflow.setType(recharge.getType());
            amount=recharge.getAmount();
            if(remark==null){
                remark=recharge.getRemark();
            }
        }else{
            cashflow.setType(type);
        }
        cashflow.setAmount(amount);
        cashflow.setPrebalance(
                amount.add(customer.getPrebalance() == null ? BigDecimal.ZERO : customer.getPrebalance()));
        cashflow.setRemark(remark);
        String guid = IdUtils.fastSimpleUUID();
        cashflow.setGuid(guid);
        cashflow.setOperatorid(user.getGuid());
        cashflow.setOperator(user.getNickName());
        cashflow.setCreatetime(DateUtils.getNowDate());
        cashflowMapper.insertCashflow(cashflow);

        customer.setPrebalance(customer.getPrebalance()==null?amount:customer.getPrebalance().add(amount));
        customer.setCurrprebalance(customer.getCurrprebalance()==null?amount:customer.getCurrprebalance().add(amount));
    }

    @Override
    public BasePojo getBaseById(Long id) {
        return customerMapper.selectCustomerByNewId(id);
    }

    @Override
    public BasePojo getBaseByCode(String code) {
        return null;
    }
}
